import { useEffect, useState, useCallback, useRef } from 'react';

interface UseInfiniteScrollOptions {
  onLoadMore: () => Promise<void>;
  threshold?: number; // 距离底部多少px时触发加载
  hasMore?: boolean; // 是否还有更多数据
  disabled?: boolean;
}

interface InfiniteScrollState {
  loading: boolean;
  hasMore: boolean;
}

/**
 * 无限滚动 Hook
 *
 * 用法:
 * ```tsx
 * const { loading, hasMore } = useInfiniteScroll({
 *   onLoadMore: async () => {
 *     await fetchMoreData();
 *   },
 *   hasMore: hasMoreData,
 *   threshold: 200,
 * });
 * ```
 */
export const useInfiniteScroll = ({
  onLoadMore,
  threshold = 200,
  hasMore = true,
  disabled = false,
}: UseInfiniteScrollOptions): InfiniteScrollState => {
  const [loading, setLoading] = useState(false);
  const isLoadingRef = useRef(false);

  const handleScroll = useCallback(async () => {
    if (disabled || !hasMore || isLoadingRef.current) return;

    // 计算是否到达底部
    const scrollTop = window.scrollY || document.documentElement.scrollTop;
    const scrollHeight = document.documentElement.scrollHeight;
    const clientHeight = window.innerHeight;

    const distanceToBottom = scrollHeight - (scrollTop + clientHeight);

    if (distanceToBottom < threshold) {
      isLoadingRef.current = true;
      setLoading(true);

      try {
        await onLoadMore();
      } catch (error) {
        console.error('Load more failed:', error);
      } finally {
        setLoading(false);
        isLoadingRef.current = false;
      }
    }
  }, [disabled, hasMore, threshold, onLoadMore]);

  useEffect(() => {
    if (disabled || !hasMore) return;

    // 使用节流优化滚动性能
    let ticking = false;

    const scrollListener = () => {
      if (!ticking) {
        window.requestAnimationFrame(() => {
          handleScroll();
          ticking = false;
        });
        ticking = true;
      }
    };

    window.addEventListener('scroll', scrollListener, { passive: true });

    return () => {
      window.removeEventListener('scroll', scrollListener);
    };
  }, [handleScroll, disabled, hasMore]);

  return {
    loading,
    hasMore,
  };
};
